/*
 * ExpressionMesh.cpp
 *
 *  Created on: 13 févr. 2011
 *      Author: elendir
 */

#include "ExpressionMesh.h"
#include <math.h>
#include "Constants.h"
#include <GL/gl.h>
#include <GL/glext.h>
#include <GL/glx.h>
#include <stdio.h>

ExpressionMesh::ExpressionMesh(Expression* treeBase, Variable* phi, Variable* theta, unsigned int phiStep, unsigned int thetaStep) {
	m_expression = treeBase;
	m_phi = phi;
	m_theta = theta;
	m_phiStep = phiStep;
	m_thetaStep = thetaStep;
	FillVertexBuffer();
	//FillIndexBuffer();

}

ExpressionMesh::~ExpressionMesh() {
	//delete m_model;
}

void ExpressionMesh::Draw() {
	//glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
	/*glEnableClientState(GL_VERTEX_ARRAY);
	glEnableClientState(GL_COLOR_ARRAY);
	glColorPointer(3, GL_FLOAT, 0, &*m_vColors.begin());
	glVertexPointer(3, GL_FLOAT, 0, &*m_vVertices.begin());
	glDrawElements(GL_QUADS, m_nVertexCount, GL_UNSIGNED_INT,  &*m_vIndices.begin());
	glDisableClientState(GL_VERTEX_ARRAY);
	glDisableClientState(GL_COLOR_ARRAY);*/
	int phiDelta = m_phiStep;
    int thetaDelta = m_thetaStep;
	glBegin(GL_LINES);
		for(int i=0; i<thetaDelta; i+=1) {
			for(int j=0; j<phiDelta; j+=1) {
				ExpressionVertex v1 = m_vVertices.at(((i+1)*phiDelta) + j+1);
				ExpressionVertex v2 = m_vVertices.at((i*phiDelta) + j+1);
				ExpressionVertex v3 = m_vVertices.at((i*phiDelta) + j);
				ExpressionVertex v4 = m_vVertices.at(((i+1)*phiDelta) + j);

				glVertex3d(v1.x, v1.y, v1.z);
				glVertex3d(v2.x, v2.y, v2.z);

				glVertex3d(v3.x, v3.y, v3.z);
				glVertex3d(v4.x, v4.y, v4.z);
			}
		}

	glEnd();
}

void ExpressionMesh::FillVertexBuffer() {
	//Init theta and phi to their lower bound
	printf("Filling vertex buffer");
	for(float theta=0.0f; theta <= MATH_PI+(MATH_PI/m_thetaStep); theta+= MATH_PI/ (float)m_thetaStep) {
		for(float phi = 0.0f; phi <= 2*MATH_PI+(2*MATH_PI/m_phiStep); phi+= 2*MATH_PI/ (float)m_phiStep) {
			m_phi->SetValue(phi);
			m_theta->SetValue(theta);
			ExpressionVertex newVertex;
			this->FillCartesianCoordinates(&newVertex, m_expression->ProcessValue(), phi, theta);
			m_vVertices.push_back(newVertex);
			m_nVertexCount++;
		}
	}
}

/*void ExpressionMesh::FillIndexBuffer() {
	printf("Filling index buffer");
	int phiDelta = m_phi->GetStepCount();
	int thetaDelta = m_theta->GetStepCount();
	for(int i=0; i<thetaDelta; i+=1) {
		for(int j=0; j<phiDelta; j+=1) {
			m_vIndices.push_back((j+1)*thetaDelta + (i+1));
			m_vIndices.push_back((j+1)*thetaDelta + i);
			m_vIndices.push_back(j*thetaDelta + i+1);
			m_vIndices.push_back(j*thetaDelta + i);
		}
	}
}*/

void ExpressionMesh::FillCartesianCoordinates(ExpressionVertex *vertex, float radius, float phi, float theta) {
	float x = radius * sin(phi) * sin(theta);
	float y = radius * cos(theta);
	float z = radius * sin(theta) * cos(phi);
	vertex->x = x;
	vertex->y = y;
	vertex->z = z;
}
